package com.robertux.leaderboard.util;

import java.io.ByteArrayInputStream;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelHelper {
	public static CellStyle defaultStyle = null;
	public static Map<Integer, CellStyle> estilosCelda = new HashMap<Integer, CellStyle>();
	public static int ESTILO_DEFAULT = 0;
	public static int ESTILO_FONDO_VERDE = 1;
	public static int ESTILO_FONDO_GRIS = 2;
	public static int ESTILO_FONDO_ORO = 3;
	public static int ESTILO_FONDO_LAVANDA = 4;
	public static int ESTILO_FONDO_TURQUESA = 5;
	
	public static int ESTILO_FONDO_BLANCO_PORCENTAJE = 6;
	public static int ESTILO_FONDO_BLANCO_CANTIDAD = 7;
	public static int ESTILO_FONDO_VERDE_CANTIDAD = 8;
	public static int ESTILO_FONDO_VERDE_MONEDA = 9;
	public static int ESTILO_DEFAULT_ALIGN_IZQUIERDA = 10;
	public static int ESTILO_DEFAULT_BORDES = 11;
	public static int ESTILO_FONDO_AZUL_AMARILLO = 12;
	public static int ESTILO_FONDO_VERDE_LIMA = 13;
	public static int ESTILO_FONDO_ROJO = 14;
	public static int ESTILO_FONDO_AMARILLO = 15;
	public static int ESTILO_FONDO_VERDE_PORCENTAJE = 16;
	public static int ESTILO_FONDO_BLANCO_VERDE_PORCENTAJE = 17;
	public static HSSFPalette customPalette;
	
	public static void crearDefaultStyle(Workbook wb) {
	defaultStyle = wb.createCellStyle();
	}
	
	public static void crearDefaultStyles(Workbook wb) {
		customPalette = ((HSSFWorkbook)wb).getCustomPalette();
		customPalette.setColorAtIndex(HSSFColor.GREEN.index, (byte)78, (byte)226, (byte)87);
		
		estilosCelda.put(ESTILO_DEFAULT, wb.createCellStyle());
		estilosCelda.get(ESTILO_DEFAULT).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_DEFAULT_ALIGN_IZQUIERDA, wb.createCellStyle());
		estilosCelda.get(ESTILO_DEFAULT_ALIGN_IZQUIERDA).setAlignment(CellStyle.ALIGN_LEFT);
		
		estilosCelda.put(ESTILO_DEFAULT_BORDES, wb.createCellStyle());
		estilosCelda.get(ESTILO_DEFAULT_BORDES).setAlignment(CellStyle.ALIGN_CENTER);
		aplicarBordes(estilosCelda.get(ESTILO_DEFAULT_BORDES));
		
		estilosCelda.put(ESTILO_FONDO_VERDE, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_VERDE).setFillForegroundColor(HSSFColor.GREEN.index);
		estilosCelda.get(ESTILO_FONDO_VERDE).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_VERDE).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_GRIS, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_GRIS).setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		estilosCelda.get(ESTILO_FONDO_GRIS).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_GRIS).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_ORO, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_ORO).setFillForegroundColor(HSSFColor.GOLD.index);
		estilosCelda.get(ESTILO_FONDO_ORO).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_ORO).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_LAVANDA, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_LAVANDA).setFillForegroundColor(HSSFColor.LAVENDER.index);
		estilosCelda.get(ESTILO_FONDO_LAVANDA).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_LAVANDA).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_TURQUESA, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_TURQUESA).setFillForegroundColor(HSSFColor.TURQUOISE.index);
		estilosCelda.get(ESTILO_FONDO_TURQUESA).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_TURQUESA).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_BLANCO_PORCENTAJE, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_BLANCO_PORCENTAJE).setDataFormat((short)0xa);
		estilosCelda.get(ESTILO_FONDO_BLANCO_PORCENTAJE).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_BLANCO_CANTIDAD, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_BLANCO_CANTIDAD).setDataFormat((short)1);
		estilosCelda.get(ESTILO_FONDO_BLANCO_CANTIDAD).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_VERDE_CANTIDAD, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_VERDE_CANTIDAD).setFillForegroundColor(HSSFColor.GREEN.index);
		estilosCelda.get(ESTILO_FONDO_VERDE_CANTIDAD).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_VERDE_CANTIDAD).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_VERDE_MONEDA, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_VERDE_MONEDA).setDataFormat((short)7);
		estilosCelda.get(ESTILO_FONDO_VERDE_MONEDA).setFillForegroundColor(HSSFColor.GREEN.index);
		estilosCelda.get(ESTILO_FONDO_VERDE_MONEDA).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_VERDE_MONEDA).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_AZUL_AMARILLO, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_AZUL_AMARILLO).setFillForegroundColor(HSSFColor.DARK_BLUE.index);
		estilosCelda.get(ESTILO_FONDO_AZUL_AMARILLO).setFillPattern(CellStyle.SOLID_FOREGROUND);
		
		HSSFFont boldFont = (HSSFFont)wb.createFont();
		boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		boldFont.setColor(HSSFColor.YELLOW.index);
		estilosCelda.get(ESTILO_FONDO_AZUL_AMARILLO).setFont(boldFont);
		
		estilosCelda.put(ESTILO_FONDO_VERDE_LIMA, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_VERDE_LIMA).setFillForegroundColor(HSSFColor.LIME.index);
		estilosCelda.get(ESTILO_FONDO_VERDE_LIMA).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_VERDE_LIMA).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_ROJO, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_ROJO).setFillForegroundColor(HSSFColor.RED.index);
		estilosCelda.get(ESTILO_FONDO_ROJO).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_ROJO).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_AMARILLO, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_AMARILLO).setFillForegroundColor(HSSFColor.YELLOW.index);
		estilosCelda.get(ESTILO_FONDO_AMARILLO).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_AMARILLO).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_VERDE_PORCENTAJE, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_VERDE_PORCENTAJE).setFillForegroundColor(HSSFColor.GREEN.index);
		estilosCelda.get(ESTILO_FONDO_VERDE_PORCENTAJE).setFillPattern(CellStyle.SOLID_FOREGROUND);
		estilosCelda.get(ESTILO_FONDO_VERDE_PORCENTAJE).setDataFormat((short)0xa);
		estilosCelda.get(ESTILO_FONDO_VERDE_PORCENTAJE).setAlignment(CellStyle.ALIGN_CENTER);
		
		estilosCelda.put(ESTILO_FONDO_BLANCO_VERDE_PORCENTAJE, wb.createCellStyle());
		estilosCelda.get(ESTILO_FONDO_BLANCO_VERDE_PORCENTAJE).setDataFormat((short)0xa);
		estilosCelda.get(ESTILO_FONDO_BLANCO_VERDE_PORCENTAJE).setAlignment(CellStyle.ALIGN_CENTER);
		
		HSSFFont boldGreenFont = (HSSFFont)wb.createFont();
		boldGreenFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		boldGreenFont.setColor(HSSFColor.SEA_GREEN.index);
		estilosCelda.get(ESTILO_FONDO_BLANCO_VERDE_PORCENTAJE).setFont(boldGreenFont);
	}
	
	public static Cell crearCelda(int posicion, String valor, Row fila, int estilo) {
		Cell celda = fila.createCell(posicion);
		celda.setCellValue(valor);
		if(estilosCelda.containsKey(estilo)) {
			celda.setCellStyle(estilosCelda.get(estilo));
		}
	    
	    return celda;
	}
	
	public static Cell crearCelda(int posicion, int valor, Row fila, int estilo) {
		Cell celda = fila.createCell(posicion);
		celda.setCellValue(valor);
		if(estilosCelda.containsKey(estilo)) {
			celda.setCellStyle(estilosCelda.get(estilo));
		}
		
		return celda;
	}
	
	public static Cell crearCelda(int posicion, double valor, Row fila, int estilo) {
		Cell celda = fila.createCell(posicion);
		celda.setCellValue(valor);
		if(estilosCelda.containsKey(estilo)) {
			celda.setCellStyle(estilosCelda.get(estilo));
		}
		
		return celda;
	}
	
	public static void crearFilaCeldas(int posInicial, String[] valores, Row fila, boolean debeAplicarBordes, int indiceColor) {
		for(String valorFila: valores) {
			Cell celda = crearCelda(posInicial++, valorFila, fila, ESTILO_DEFAULT);
			if(debeAplicarBordes) {
				celda.setCellStyle(estilosCelda.get(ESTILO_DEFAULT_BORDES));
			}
			if(estilosCelda.containsKey(indiceColor)) {
				celda.setCellStyle(estilosCelda.get(indiceColor));
			}
		}
	}
	
	public static void crearFilaCeldas(int posInicial, String[] valores, Row fila, boolean DebeAplicarBordes) {
		crearFilaCeldas(posInicial, valores, fila, DebeAplicarBordes, ESTILO_DEFAULT);
	}
	
	public static Cell aplicarBordes(Cell celda) {
	    celda.getCellStyle().setBorderBottom(CellStyle.BORDER_THIN);
	    celda.getCellStyle().setBottomBorderColor(IndexedColors.BLACK.getIndex());
	    celda.getCellStyle().setBorderLeft(CellStyle.BORDER_THIN);
	    celda.getCellStyle().setLeftBorderColor(IndexedColors.BLACK.getIndex());
	    celda.getCellStyle().setBorderRight(CellStyle.BORDER_THIN);
	    celda.getCellStyle().setRightBorderColor(IndexedColors.BLACK.getIndex());
	    celda.getCellStyle().setBorderTop(CellStyle.BORDER_THIN);
	    celda.getCellStyle().setTopBorderColor(IndexedColors.BLACK.getIndex());
	    
	    return celda;
	}
	
	public static void aplicarBordes(CellStyle style) {
		style.setBorderBottom(CellStyle.BORDER_THIN);
		style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setRightBorderColor(IndexedColors.BLACK.getIndex());
		style.setBorderTop(CellStyle.BORDER_THIN);
		style.setTopBorderColor(IndexedColors.BLACK.getIndex());
	}
	
	public static void aplicarBordes(CellRangeAddress region, Sheet hoja, Workbook workbook) {
		RegionUtil.setBorderTop(CellStyle.BORDER_THIN, region, hoja, workbook);
		RegionUtil.setBorderLeft(CellStyle.BORDER_THIN, region, hoja, workbook);
		RegionUtil.setBorderRight(CellStyle.BORDER_THIN, region, hoja, workbook);
		RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, region, hoja, workbook);
	}
	
	/*public static Cell aplicarFillColor(Cell celda, IndexedColors color) {
	    celda.getCellStyle().setFillForegroundColor(color.getIndex());
	    celda.getCellStyle().setFillPattern(CellStyle.SOLID_FOREGROUND);
		return celda;
	}*/
	
	public static Cell aplicarEstilo(Cell celda, int estilo) {
		celda.setCellStyle(estilosCelda.get(estilo));
		return celda;
	}
	
	/*public static Cell aplicarTextColor(Cell celda, IndexedColors color) {
		Font font = celda.getRow().getSheet().getWorkbook().createFont();
		font.setColor(HSSFColor.RED.index);
		celda.getCellStyle().setFont(font);

		return celda;
	}*/
	
	/*public static Cell alinear(Cell celda, short alineacion) {
		celda.getCellStyle().setAlignment(alineacion);
		
		return celda;
	}*/
	
	/*public static Cell aplicarFormato(Cell celda, short formato) {
		celda.getCellStyle().setDataFormat(formato);
		
		return celda;
	}*/
	
	public static String[][] getFileContent(byte[] fileContent, String fileExt) {
		Logger logger = Logger.getLogger(ExcelHelper.class);
		List<String[]> content = new ArrayList<String[]>();
		Workbook wb = null;
		if(fileExt.equals("xls")) {
			try {
				wb = new HSSFWorkbook(new ByteArrayInputStream(fileContent));
			} catch (Exception e) {
				logger.error("Error cargando el contenido del archivo Excel: " + e.getMessage(), e);
			}
		} else if (fileExt.equals("xlsx")) {
			try {
				wb = new XSSFWorkbook(new ByteArrayInputStream(fileContent));
			} catch (Exception e) {
				logger.error("Error cargando el contenido del archivo Excel: " + e.getMessage(), e);
			}
		}
		
		if(wb != null) {
			Sheet sheet = wb.getSheetAt(0);
			Iterator<Row> rIterator = sheet.rowIterator();
			while(rIterator.hasNext()) {
				Row row = (Row)rIterator.next();
				Iterator<Cell> cIterator = row.cellIterator();
				StringBuilder sb = new StringBuilder();
				List<String> cellContent = new ArrayList<String>();
				while(cIterator.hasNext()) {
					Cell cell = (Cell)cIterator.next();
					String cellValue = "";
					try {
						switch(cell.getCellType()) {
						case Cell.CELL_TYPE_STRING:
							cellValue = cell.getStringCellValue();
							break;
						case Cell.CELL_TYPE_NUMERIC:
							NumberFormat f = NumberFormat.getNumberInstance();
							f.setGroupingUsed(false);
							cellValue = f.format(cell.getNumericCellValue());
							break;
						case Cell.CELL_TYPE_BOOLEAN:
							cellValue = String.valueOf(cell.getBooleanCellValue());
							break;
						}
					} catch (Exception e) {
						logger.error("Error: " + e.getMessage());
					}
					cellContent.add(cellValue);
					
					sb.append("[" + cell.getRowIndex() + ", " + cell.getColumnIndex() + "] = " + cellValue).append("\t\t");
				}
				content.add(cellContent.toArray(new String[0]));
			}
		}
		
		return content.toArray(new String[0][]);
	}
}
